package com.boarsoft.boar.sequence.service;

import com.boarsoft.boar.sequence.entity.SequenceSegment;

public interface SequenceService {
	/**
	 * <p>
	 * 新增号段时，总是查询结束值最大的记录，并加一后作为新号段的起始值，<br>
	 * 再用其结束值与起始值的差作为号段长计算其结束值。查不到才去查序列监息表。<br>
	 * 插入时如果违反了唯一性（主键）约束则重试上述过程。
	 * </p>
	 * 
	 * @param catalog
	 * @param code
	 * @param tag
	 *            IP地址或UUID
	 * @return
	 */
	SequenceSegment getSegment(String catalog, String code, String tag);

	/**
	 * 针对全局递增（不分片）且不可回收（可丢失）的方案（方案三）<br>
	 * 从数据库查询当前序列的当前值加一，并以乐观锁形式更新
	 * 
	 * @param catalog
	 * @param code
	 * @return
	 */
	long next(String catalog, String code);

	/**
	 * 针对全局递增（不分片）且可回收（不可回收）的方案（方案四）<br>
	 * 先从回收号码队列取，取不到再采用方案三。<br>
	 * 退号时先写回收号码表，再入队。<br>
	 * 启动时从回收号码表装载号码入队。<br>
	 * 
	 * @param catalog
	 * @param code
	 * @return
	 */
	long take(String catalog, String code);

	/**
	 * 归还此前拿走的序号（仅针对方案四）<br>
	 * 
	 * @param catalog
	 * @param code
	 * @param no
	 */
	void back(String catalog, String code, long no);

	/**
	 * 支持自选号的序列生成
	 * 
	 * @param catalog
	 *            系统名
	 * @param code
	 *            序列名
	 * @param selNum
	 *            自选号
	 * @return
	 */
	long next(String catalog, String code, String selNum);
}
